/////////////////////////////////////////////////////////////////////////////
// Copyright(c) 2012-2015 purang All Rights Reserved
// Name:        socket_impl.h
// Purpose:     
// Author:      syy
// Modified by: 
// Created:     2014/8/28 13:07
// RCS-ID:      
// Licence:     
/////////////////////////////////////////////////////////////////////////////
#ifndef _SOCKET_IMPL_H_
#define _SOCKET_IMPL_H_
#include "socket_wrapper.h"
#include "socket_proxy.h"
#include "buffer_wrapper.h"
#include "core/system/thread_wrapper.h"
#include "core/system/event_wrapper.h"
#include "core/system/atomic32.h"
#include "qbprotocol/include/message_process_data.h"
#include <string>

namespace qb
{
	struct ISocketObserver
	{
		virtual void OnConnected() = 0;
		virtual void OnSendFailed() = 0;
		virtual void OnRecvFailed() = 0;  	
        virtual void OnRecvMessage(MESSAGE_SHARED_PTR msp) = 0;
        virtual void OnRecvMessage2(const char* buf, uint32_t buf_size) = 0;
	};
	class CSocketImpl
	{
	public:
		CSocketImpl();
		virtual ~CSocketImpl();
		virtual int32_t Connect(const char* ip_address,uint16_t port,uint16_t socket_type);
		virtual int32_t Disconnect();
		virtual int32_t Send(const char* buff,uint32_t bytes);
		virtual void SetProxy(
			ProxyType proxy,
			const char* host,
			uint16_t port,
			const char* username,
			const char* password,
			const char* domain);

		virtual int32_t RegisterSocketObserver(ISocketObserver* observer);
		virtual int32_t DeRegisterSocketObserver();

		virtual uint32_t GetTargetIP();
		virtual uint16_t GetTargetPort();
		virtual void SetSocks5UdpProxy(bool use_udp);

	private:
		static bool ThreadFunSend(void* args);
		bool ThreadProcessSend(void* args);
		static bool ThreadFunRecv(void* args);
		bool ThreadProcessRecv(void* args);
		int32_t Create(uint16_t socket_type);
		int32_t Close(int32_t socket);
		int32_t SetOpt(int32_t socket);
		void StopThread(ThreadWrapper** thread_);
		virtual int32_t GetSocket();

	protected:
		CSocketWrapper				m_socket;
		std::string					m_ipaddress;
		uint16_t					m_port;
		uint16_t					m_socket_type;

		ISocketObserver*			m_observer;
		CriticalSectionWrapper&		m_critSect;
		CriticalSectionWrapper&		m_crit_interface;

		EventWrapper&				m_event_send;
		ThreadWrapper*				m_thread_send;
		Atomic32					m_exit_flag_send;
		BufferQueue					m_send_buffer;

		ThreadWrapper*				m_thread_recv;
		Atomic32					m_exit_flag_recv;
		BufferQueue					m_recv_buffer;

		CSocketProxy				m_proxy;
		CSocketImpl*				m_udp_associate;
		bool						m_udp_proxy;
	};
}
#endif // _SOCKET_IMPL_H_
